// -------------------------------------------------
// BlinKit - BlinKit Library
// -------------------------------------------------
//   File Name: page_popup_host_window.cpp
// Description: PagePopupHostWindow Class
//      Author: Ziming Li
//     Created: 2022-04-27
// -------------------------------------------------
// Copyright (C) 2022 MingYang Software Technology.
// -------------------------------------------------

#include "./page_popup_host_window.h"

#include <windowsx.h>
#include "blinkit/blink/renderer/web/web_page_popup.h"
#include "blinkit/ui/web_view_impl.h"
#include "blinkit/win/web_view_host_window.h"

namespace BlinKit {

PagePopupHostWindow::PagePopupHostWindow(WebPage &page) : WebPageHostWindow(&page, nullptr)
{
    WebPageHostWindow::DisableMouseLeaveTracking();
}

#ifndef NDEBUG
PagePopupHostWindow::~PagePopupHostWindow(void)
{
    ASSERT(!HasHWND());
}
#endif

void PagePopupHostWindow::Close(void)
{
    OwnerHostWindow()->StopPagePopupSession();
}

WebPagePopup* PagePopupHostWindow::GetWebPagePopup(void) const
{
    return static_cast<WebPagePopup *>(GetWebPage());
}

BOOL PagePopupHostWindow::OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
{
    RECT rc;
    GetClientRect(hwnd, &rc);

    HDC dc = GetDC(hwnd);
    InitializePaintSession(dc, rc.right, rc.bottom);
    ReleaseDC(hwnd, dc);

    return TRUE;
}

void PagePopupHostWindow::OnDestroy(HWND hwnd)
{
    DetachHWND();
}

void PagePopupHostWindow::OnSize(HWND, UINT state, int cx, int cy)
{
    const IntSize size(cx, cy);
    if (GetWebPage()->Size() != size)
        WebPageHostWindow::Resize(size);
}

WebViewHostWindow* PagePopupHostWindow::OwnerHostWindow(void) const
{
    return static_cast<WebViewHostWindow *>(GetWebPagePopup()->Owner()->Host());
}

bool PagePopupHostWindow::ProcessMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT &result)
{
    bool handled = true;
    switch (Msg)
    {
        case WM_SIZE:
            HANDLE_WM_SIZE(hWnd, wParam, lParam, OnSize);
            break;
        case WM_CREATE:
            result = HANDLE_WM_CREATE(hWnd, wParam, lParam, OnCreate);
            break;
        case WM_DESTROY:
            HANDLE_WM_DESTROY(hWnd, wParam, lParam, OnDestroy);
            break;
        default:
            handled = WebPageHostWindow::ProcessMessage(hWnd, Msg, wParam, lParam, result);
    }
    return handled;
}

void PagePopupHostWindow::SetWindowRect(const IntRect &rect)
{
    if (!HasHWND())
        OwnerHostWindow()->StartPagePopupSession(this);

    POINT pt = { 0 };
    ::ClientToScreen(GetParent(*this), &pt);
    SetWindowPos(*this, nullptr,
        rect.x() + pt.x, rect.y() + pt.y,
        rect.width(), rect.height(),
        SWP_NOZORDER | SWP_NOACTIVATE
    );
}

void PagePopupHostWindow::Show(void)
{
    ShowWindow(*this, SW_SHOWNA);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

std::unique_ptr<WebPageHost> WebPageHost::CreateForPagePopup(WebPage &page)
{
    return std::make_unique<PagePopupHostWindow>(page);
}

} // namespace BlinKit
